package cn.tedu.tmall.passport.service.impl;

import cn.tedu.tmall.common.util.JwtUtils;
import cn.tedu.tmall.passport.dao.repository.IUserCacheRepository;
import cn.tedu.tmall.passport.pojo.param.UserLoginInfoParam;
import cn.tedu.tmall.passport.pojo.po.UserStatePO;
import cn.tedu.tmall.passport.pojo.vo.UserLoginResultVO;
import cn.tedu.tmall.passport.service.IUserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;

@Slf4j
@Service
public class UserService implements IUserService {

    private String secretKey = "fNesMDkqrJFdsfDSwAbFLJ8SnsHJ438AF72D73aKJSmfdsafdLKKAFKDSJ";

    @Autowired
    private IUserCacheRepository userCacheRepository;

    /**
     * 用户登录：
     * 验证用户名、密码，
     * 判断用户状态（是否禁用/拉黑），
     * 记录登录日志（可选），
     * 生成token
     * @param userLoginInfoParam 用户登录信息
     * @return 用户登录结果
     */
    @Override
    public UserLoginResultVO login(UserLoginInfoParam userLoginInfoParam) {
        //1.验证用户名
        String username = userLoginInfoParam.getUsername();
        //2.验证密码
        String password = userLoginInfoParam.getPassword();
        //伪造的id，应该从数据库取出
        Long userId = 1L;
        //用户生成token的Map，什么都能放，但放太多数据会使token变长，所以应该只放必要的数据
        //放入的数据越多，加密解密相对会更慢，浪费网络带宽和存储空间
        // 可选的：记录用户登录日志,登录次数 可选的业务逻辑
        //3.生成token
        Map<String, Object> claims = new HashMap<>();
        claims.put("id", userId);
        claims.put("name", username);
        String jwt = JwtUtils.generate(claims, secretKey);
        log.debug("生成用户的JWT数据：{}", jwt);
        //获取权限信息 存入到redis里
        // 1 获取 5表连查
        // 2 存储 用什么样的数据类型?
        //   不合理   list  key user_stat_+UserId(1)  value 权限列表
        //   Hash  key  user_stat_+UserId(1) hashKey
        // Map<String,Map<String,value>>
        // 1 一个人一个大map  分布式的概念
        //    数据分散 结合 用户量 5000W人  结合业务 200个管理员
        // 2 所有人共有一个大map 每个人是个小map  2
        // 实现业务,节约成本,考虑扩展性
        // 一个人一个大map  分布式的概念
        // key user_status_123 ,
        // value
        //      auth 权限列表
        //      status 用户状态
        //      time :失效时间
        UserStatePO userStatePO = new UserStatePO();
        //todo userId和enable都应该从数据库获取
        userStatePO.setId(userId);
        userStatePO.setEnable(1);
        String authorities = "[{authority:'/article/add'},{authority:'/article/detail'}]";
        userStatePO.setAuthorities(authorities);
        userCacheRepository.saveUserState(userStatePO);

        //定义返回的数据
        UserLoginResultVO userLoginResultVO = new UserLoginResultVO();
        //设置返回的数据
        userLoginResultVO.setId(userId);
        userLoginResultVO.setUsername(username);
        userLoginResultVO.setToken(jwt);
        return userLoginResultVO;
    }
}
